<script setup>
import {Message} from '@arco-design/web-vue'
import {computed, ref} from 'vue'
import {route} from "ziggy-js"

const props = defineProps({
    // 文件大小限制（MB）
    maxSize: {
        type: Number,
        default: 5
    },
    // 上传框尺寸
    size: {
        type: String,
        default: 'medium', // small, medium, large
    },
    // 提示文字
    tip: {
        type: String,
        default: ''
    }
})

const modelValue = defineModel('modelValue', { type: String, default: '' })

const action = route('admin.upload.image')
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') ?? ''
const headers = {
    'X-CSRF-TOKEN': csrfToken,
}

// 响应式状态
const isUploading = ref(false)
const errorMessage = ref('')
const previewVisible = ref(false)

// 计算属性
const hasImage = computed(() => !!modelValue.value)

// 尺寸配置
const sizeConfig = {
    small: { width: '80px', height: '80px' },
    medium: { width: '120px', height: '120px' },
    large: { width: '160px', height: '160px' }
}

const currentSize = computed(() => sizeConfig[props.size] || sizeConfig.medium)

// 事件处理
const handleSuccess = (currentFile) => {
    if (currentFile.response?.code === 200) {
        modelValue.value = currentFile.response.data.url
        Message.success('图片上传成功')
        errorMessage.value = ''
    } else {
        Message.error('图片上传失败')
        errorMessage.value = '上传失败，请重试'
    }
    isUploading.value = false
}

const handleError = (file) => {
    console.error('Upload error:', file)
    Message.error('图片上传失败')
    errorMessage.value = '上传失败，请重试'
    isUploading.value = false
}

const handleBeforeUpload = (file) => {
    // 重置状态
    errorMessage.value = ''
    isUploading.value = true

    // 文件类型验证
    const validTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']
    if (!validTypes.includes(file.type)) {
        Message.error('只支持 JPG、PNG、GIF、WEBP 格式的图片')
        isUploading.value = false
        return false
    }

    // 文件大小验证
    const maxSizeInBytes = props.maxSize * 1024 * 1024
    if (file.size > maxSizeInBytes) {
        Message.error(`文件大小不能超过 ${props.maxSize}MB`)
        isUploading.value = false
        return false
    }

    return true
}

const handleRemove = (e) => {
    e?.stopPropagation()
    modelValue.value = ''
    Message.info('已移除图片')
}

const visible = ref(false)
const handlePreview = (e) => {
    e.stopPropagation()
    e.preventDefault()
    visible.value = true
}

const handleRetry = () => {
    errorMessage.value = ''
}
</script>

<template>
    <div class="image-upload">
        <a-upload
            :action="action"
            :before-upload="handleBeforeUpload"
            :disabled="isUploading"
            :headers="headers"
            :show-file-list="false"
            :with-credentials="true"
            accept="image/jpeg,image/png,image/gif,image/webp"
            name="file"
            @error="handleError"
            @success="handleSuccess"
        >
            <template #upload-button>
                <div
                    :class="{
            'uploading': isUploading,
            'has-image': hasImage,
            'has-error': errorMessage,
            [`size-${size}`]: true
          }"
                    :style="{
            width: currentSize.width,
            height: currentSize.height
          }"
                    class="upload-area"
                >
                    <!-- 上传中状态 -->
                    <div v-if="isUploading" class="upload-state uploading-state">
                        <a-spin :size="size === 'small' ? 'small' : 'default'" />
                        <span class="state-text">上传中</span>
                    </div>

                    <!-- 已上传图片状态 -->
                    <div v-else-if="hasImage" class="upload-state image-state">
                        <img :src="modelValue" alt="预览图片" class="preview-image" />
                        <div class="image-overlay">
                            <div class="action-buttons">
                                <a-tooltip content="预览">
                                    <a-button
                                        class="action-btn"
                                        size="mini"
                                        type="text"
                                        @click="handlePreview"
                                    >
                                        <icon-eye />
                                    </a-button>
                                </a-tooltip>
                                <a-tooltip content="删除">
                                    <a-button
                                        class="action-btn"
                                        size="mini"
                                        status="danger"
                                        type="text"
                                        @click="handleRemove"
                                    >
                                        <icon-delete />
                                    </a-button>
                                </a-tooltip>
                            </div>
                        </div>
                    </div>

                    <!-- 默认上传状态 -->
                    <div v-else class="upload-state default-state">
                        <div class="upload-icon">
                            <icon-plus />
                        </div>
                        <div class="upload-text">上传图片</div>
                    </div>
                </div>
            </template>
        </a-upload>

        <!-- 错误提示 -->
        <div v-if="errorMessage" class="error-message">
            <icon-exclamation-circle-fill class="error-icon" />
            <span class="error-text">{{ errorMessage }}</span>
            <a-button size="mini" type="text" @click="handleRetry">
                重试
            </a-button>
        </div>

        <!-- 提示文字 -->
        <div v-if="tip" class="upload-tip">
            {{ tip }}
        </div>

        <a-image-preview
            v-model:visible="visible"
            :src="modelValue"
        />
    </div>
</template>

<style lang="scss" scoped>
.image-upload {
    display: inline-flex;
    flex-direction: column;
    gap: 8px;
}

.upload-area {
    position: relative;
    border: 2px dashed var(--color-border-3);
    border-radius: 8px;
    background: var(--color-fill-2);
    transition: all 0.3s ease;
    cursor: pointer;
    overflow: hidden;

    &:hover {
        border-color: var(--color-primary-light-3);
        background: var(--color-fill-1);

        &.has-image .image-overlay {
            opacity: 1;
        }
    }

    &.uploading {
        border-color: var(--color-primary-light-3);
        background: var(--color-primary-light-1);
    }

    &.has-error {
        border-color: var(--color-danger-light-3);
        background: var(--color-danger-light-1);
    }
}

.upload-state {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
}

.default-state {
    .upload-icon {
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background: var(--color-primary-light-5);
        display: flex;
        align-items: center;
        justify-content: center;
        color: var(--color-primary);
        font-size: 14px;
        transition: all 0.3s ease;
    }

    .upload-text {
        font-size: 12px;
        color: var(--color-text-3);
        font-weight: 500;
    }
}

.uploading-state {
    .state-text {
        font-size: 12px;
        color: var(--color-text-2);
    }
}

.image-state {
    position: relative;

    .preview-image {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .image-overlay {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.5);
        display: flex;
        align-items: center;
        justify-content: center;
        opacity: 0;
        transition: opacity 0.3s ease;
    }

    .action-buttons {
        display: flex;
        gap: 8px;

        .action-btn {
            border: none;
            background: unset;
            color: #fff;
            font-size: 18px;
        }
    }
}

// 尺寸调整
.upload-area.size-small {
    .upload-icon {
        width: 20px;
        height: 20px;
        font-size: 12px;
    }

    .upload-text {
        font-size: 11px;
    }

    .action-buttons {
        gap: 4px;
    }
}

.upload-area.size-large {
    .upload-icon {
        width: 32px;
        height: 32px;
        font-size: 16px;
    }

    .upload-text {
        font-size: 14px;
    }
}

.error-message {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
    background: var(--color-danger-light-1);
    border: 1px solid var(--color-danger-light-3);
    border-radius: 4px;
    font-size: 12px;

    .error-icon {
        color: var(--color-danger);
        font-size: 12px;
    }

    .error-text {
        color: var(--color-danger);
        flex: 1;
    }
}

.upload-tip {
    font-size: 12px;
    color: var(--color-text-3);
    line-height: 1.4;
    max-width: v-bind('currentSize.width');
}

// 响应式调整
@media (max-width: 768px) {
    .upload-area {
        &.size-large {
            width: 120px !important;
            height: 120px !important;
        }
    }
}
</style>
